home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Software Vault: The Games Collection 1
/
software vault.zip
/
software vault
/
CDR10
/
ACK3D.ZIP
/
ENGINE
/
ACKRAY.C
< prev
next >
Wrap
Text File
|
1993-08-23
|
7KB
|
237 lines
/******************* ( Animation Construction Kit 3D ) ***********************/
/* Ray Casting Routines */
/* CopyRight (c) 1993 Author: Lary Myers */
/*****************************************************************************/
#include <stdlib.h>
#include <stdio.h>
#include <dos.h>
#include <mem.h>
#include <alloc.h>
#include <io.h>
#include <fcntl.h>
#include <time.h>
#include <string.h>
#include <sys\stat.h>
#include "ack3d.h"
#include "ackeng.h"
#include "ackext.h"
UCHAR yLight;
UCHAR xLight;
/****************************************************************************
** This routine cast rays along the X walls of the map to determine when **
** a wall is struck. A zero returned indicates no wall was found, else the **
** bitmap number of the wall is returned. **
** If a wall is found the variables LastY1 and iLastX are set to the map **
** coordinates of the wall and xMapPosn is the actual map coordinate. **
** **
****************************************************************************/
UINT xRay(int x,int y,int angle,ACKENG *ae)
{
UINT Color;
int i,j,mx,my;
int TablePosn;
int MapPosn,CurPosn;
int xBeg;
long xPos,xNext;
int BitmapColumn;
int xCenter,yCenter,xAdj;
int ObjPosn;
int oBegX,oBegY;
long yPos;
long yNext;
long xd,yd,sy;
long ObjDist;
xBeg = x & 0xFFC0; /* Get upper left corner of square */
yNext = yNextTable[angle]; /* PreCalc'd value of 64 * Tan(angle) */
if (angle > INT_ANGLE_270 || angle < INT_ANGLE_90)
{
xPos = xBeg + GRID_SIZE; /* Looking to the right */
xNext = GRID_SIZE; /* Positive direction */
}
else
{
xPos = xBeg; /* Looking to the left */
xNext = -GRID_SIZE; /* Negative direction */
yNext = -yNext;
}
/* Calculate the Y coordinate for the current square */
yPos = (((long)xPos - (long)x) * LongTanTable[angle]) + ((long)y << FP_SHIFT);
while (1)
{
if (xPos < 0 || xPos > GRID_XMAX ||
yPos < 0 || yPos > GRID_YMAXLONG)
break;
/************** Fixed point Y/64 * 64 X / 64 ***********/
MapPosn = ((yPos >> FP_SHIFT) & 0xFFC0) + (xPos >> 6);
/* Check to see if a wall is being struck by the ray */
if ((Color = ae->xGrid[MapPosn]) != 0)
{
xMapPosn = MapPosn; /* Hold onto the map location */
iLastX = xPos;
LastY1 = yPos;
if ((Color & 0xFF) == DOOR_XCODE) /* Is this a door? */
{
yd = (yPos >> FP_SHIFT) & 0xFFC0; /* Get the left side */
xd = yd + GRID_SIZE; /* And the right side */
ObjDist = (yPos + (yNext >> 1)) >> FP_SHIFT; /* Calc door distance */
if (ObjDist < yd || ObjDist > xd) /* Is door visible? */
{
xPos += xNext; /* Nope, continue casting */
yPos += yNext; /* the ray as before */
continue;
}
LastY1 = yPos + (yNext >> 1); /* Adjust the X,Y values so */
iLastX += (xNext >> 1); /* the door is halfway in sq. */
}
if (Color & DOOR_TYPE_SECRET)
{
if (xSecretColumn != 0)
{
sy = xSecretColumn * LongTanTable[angle];
ObjDist = (yPos + sy) >> FP_SHIFT;
yd = (yPos >> FP_SHIFT) & 0xFFC0; /* Get the left side */
xd = yd + GRID_SIZE; /* And the right side */
if (ObjDist < yd || ObjDist > xd) /* Is door visible? */
{
xPos += xNext; /* Nope, continue casting */
yPos += yNext; /* the ray as before */
continue;
}
LastY1 = yPos + sy;
iLastX += xSecretColumn;
}
}
xLight = LightMap[MapPosn];
return(Color);
}
xPos += xNext; /* Next X coordinate (fixed at 64 or -64) */
yPos += yNext; /* Next calculated Y coord for a delta of X */
}
return(0); /* Return that no wall was found */
}
/****************************************************************************
** This routine cast rays along the Y walls of the map to determine when **
** a wall is struck. A zero returned indicates no wall was found, else the **
** bitmap number of the wall is returned. **
** If a wall is found the variables LastX1 and iLastY are set to the map **
** coordinates of the wall and xMapPosn is the actual map coordinate. **
** **
****************************************************************************/
UINT yRay(int x,int y,int angle,ACKENG *ae)
{
UINT Color;
int i,j,mx,my;
int MapPosn;
int yBeg;
long yPos,yNext;
int BitmapColumn;
int xCenter,yCenter,yAdj;
int ObjPosn;
int oBegX;
long xPos;
long xNext;
long xd,yd,ObjDist,sx;
yBeg = y & 0xFFC0; /* Same as div 64 then mul 64 */
xNext = xNextTable[angle]; /* Pre-calc'd value of 64 / tan(angle) */
if (angle < INT_ANGLE_180)
{
yPos = yBeg + GRID_SIZE; /* Looking down */
yNext = GRID_SIZE; /* Positive direction */
}
else
{
yPos = yBeg; /* Looking up */
yNext = -GRID_SIZE; /* Negative direction */
xNext = -xNext;
}
/* Calculate the X coordinate for the current square */
xPos = (((long)yPos - (long)y) * LongInvTanTable[angle]) + ((long)x << FP_SHIFT);
oBegX = 0;
while (1)
{
if (xPos < 0 || xPos > GRID_XMAXLONG ||
yPos < 0 || yPos > GRID_YMAX)
break;
/*********** Y/64 * 64 Fixed point and /64 ******/
MapPosn = (yPos & 0xFFC0) + (xPos >> (FP_SHIFT+6));
/** Check for a wall being struck **/
if ((Color = ae->yGrid[MapPosn]) != 0)
{
yMapPosn = MapPosn; /* Hold onto map position */
LastX1 = xPos;
iLastY = yPos;
if ((Color & 0xFF) == DOOR_YCODE) /* Is this a door? */
{
yd = (xPos >> FP_SHIFT) & 0xFFC0; /* Calc top side of square */
xd = yd + GRID_SIZE; /* And bottom side of square */
ObjDist = (xPos + (xNext >> 1)) >> FP_SHIFT;
if (ObjDist < yd || ObjDist > xd) /* Is door visible? */
{
xPos += xNext; /* No, continue on with ray cast */
yPos += yNext;
continue;
}
LastX1 = xPos + (xNext >> 1); /* Adjust coordinates so door is */
iLastY += (yNext >> 1); /* Halfway into wall */
}
if (Color & DOOR_TYPE_SECRET)
{
if (ySecretColumn != 0)
{
sx = ySecretColumn * LongInvTanTable[angle];
ObjDist = (xPos + sx) >> FP_SHIFT;
yd = (xPos >> FP_SHIFT) & 0xFFC0; /* Get the top side */
xd = yd + GRID_SIZE; /* And the bottom side */
if (ObjDist < yd || ObjDist > xd) /* Is door visible? */
{
xPos += xNext; /* Nope, continue casting */
yPos += yNext; /* the ray as before */
continue;
}
LastX1 = xPos + sx;
iLastY += ySecretColumn;
}
}
yLight = LightMap[MapPosn];
return(Color);
}
xPos += xNext; /* Next calculated X value for delta Y */
yPos += yNext; /* Next fixed value of 64 or -64 */
if (++oBegX > 64) /* Check a maximum number of squares */
break;
}
return(0); /* Return here if no Y wall is found */
}